#include <physics/ShapeLoader.h>

#include <Box2D/Collision/Shapes/b2Shape.h>
#include <Box2D/Collision/Shapes/b2ChainShape.h>
#include <Box2D/Collision/Shapes/b2CircleShape.h>
#include <Box2D/Collision/Shapes/b2EdgeShape.h>
#include <Box2D/Collision/Shapes/b2PolygonShape.h>

namespace liba
{
namespace converter
{
	converter::EnumPair<char, b2Shape::Type> ShapeTypeNames[] = 
	{
		converter::MakeEnumPair("Circle", b2Shape::e_circle),
		converter::MakeEnumPair("Chain", b2Shape::e_chain),
		converter::MakeEnumPair("Edge", b2Shape::e_edge),
		converter::MakeEnumPair("Polygon", b2Shape::e_polygon)
	};

	template<> struct ConverterTraits<char, b2Shape::Type>
		:	public ConverterTraitsEnumBase<char, b2Shape::Type, ShapeTypeNames>
	{};

} // namespace converter
} // namespace liba


namespace physics
{

bool ShapeLoader::on_attribute(xml::Provider *prov, const std::string &name, const std::string &value)
{
	if(name == "Type")
	{
		if(!converter::convert(value, &shapeType))
			return false;

		std::auto_ptr <ShapeLoader> loader;
		if(shapeType == b2Shape::e_circle)
			loader.reset(new ConcreteShapeLoader <b2CircleShape> ());
		else if(shapeType == b2Shape::e_chain)
			loader.reset(new ConcreteShapeLoader <b2ChainShape> ());
		else if(shapeType == b2Shape::e_polygon)
			loader.reset(new ConcreteShapeLoader <b2PolygonShape> ());
		else if(shapeType == b2Shape::e_edge)
			loader.reset(new ConcreteShapeLoader <b2EdgeShape> ());

		if(!prov->parse_object(loader.get()))
			return false;

		shape = loader->GetShape();

		return true;
	}

	return false;
}

}	// namespace physics